package com.bjsdzk.collector.platform.coap;

import com.bjsdzk.collector.core.Result;
import com.bjsdzk.collector.core.ResultGenerator;
import com.bjsdzk.collector.platform.coap.utils.Constant;
import com.bjsdzk.collector.platform.coap.utils.HttpsUtil;
import com.bjsdzk.collector.platform.coap.utils.JsonUtil;
import com.bjsdzk.collector.platform.coap.utils.StreamClosedHttpResponse;

import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.Map;

@RestController
@RequestMapping("/telecom-subscribe")
public class SubscribeController {
	private static Logger logger = LoggerFactory.getLogger(SubscribeController.class);

    @GetMapping("/deviceAdd")
    public Result addDevice(){
        String bodySubscribe = handler(Constant.DEVICE_ADDED,Constant.DEVICE_ADDED_CALLBACK_URL);
        return ResultGenerator.genSuccessResult(bodySubscribe);
    }

    @GetMapping("/deviceInfoChanged")
    public Result deviceInfoChanged(){
        String bodySubscribe = handler(Constant.DEVICE_INFO_CHANGED,Constant.DEVICE_INFO_CHANGED_CALLBACK_URL);
        return ResultGenerator.genSuccessResult(bodySubscribe);
    }

    @GetMapping("/deviceDataChanged")
    public Result deviceDataChanged(){
        String bodySubscribe = handler(Constant.DEVICE_DATA_CHANGED,Constant.DEVICE_DATA_CHANGED_CALLBACK_URL);
        return ResultGenerator.genSuccessResult(bodySubscribe);
    }

    @GetMapping("/deviceDeleted")
    public Result deviceDeleted(){
        String bodySubscribe = handler(Constant.DEVICE_DELETED,Constant.DEVICE_DELETED_CALLBACK_URL);
        return ResultGenerator.genSuccessResult(bodySubscribe);
    }

    @GetMapping("/deletedeviceAdd")
    public Result deletedeviceAdd(){
        String bodySubscribe = deletehandler(Constant.DEVICE_ADDED,Constant.DEVICE_ADDED_CALLBACK_URL);
        return ResultGenerator.genSuccessResult(bodySubscribe);
    }
    
    @GetMapping("/query")
    public Result getSubscribe(@RequestParam(required = false) String id){
        if(StringUtils.isEmpty(id)){
            return ResultGenerator.genFailResult("id is null");
        }
        String bodySubscribe = "";
        try {
            HttpsUtil httpsUtil = new HttpsUtil();
            httpsUtil.initSSLConfigForTwoWay();
            // Authentication，get token
            String accessToken = login(httpsUtil);
            //Please make sure that the following parameter values have been modified in the Constant file.
            String appId = Constant.APPID;
            String urlSubscribe = Constant.SUBSCRIBE_NOTIFYCATION+"/"+id+"?appId="+appId;

            Map<String, String> header = new HashMap<>();
            header.put(Constant.HEADER_APP_KEY, appId);
            header.put(Constant.HEADER_APP_AUTH, "Bearer" + " " + accessToken);

            HttpResponse httpResponse = httpsUtil.doGetWithParas(urlSubscribe,null,header);
            bodySubscribe = httpsUtil.getHttpResponseBody(httpResponse);
            System.out.print(httpResponse.getStatusLine());
            System.out.println(bodySubscribe);
            System.out.println();
        }catch (Exception e){
            e.printStackTrace();
        }
        return ResultGenerator.genSuccessResult(bodySubscribe);
    }

    @DeleteMapping("/{id}")
    public Result delSubscribe(@PathVariable String id){
        String bodySubscribe = "";
        try {
            HttpsUtil httpsUtil = new HttpsUtil();
            httpsUtil.initSSLConfigForTwoWay();
            // Authentication，get token
            String accessToken = login(httpsUtil);
            //Please make sure that the following parameter values have been modified in the Constant file.
            String appId = Constant.APPID;
            String urlSubscribe = Constant.SUBSCRIBE_NOTIFYCATION+"/"+id+"?appId="+appId;

            Map<String, String> header = new HashMap<>();
            header.put(Constant.HEADER_APP_KEY, appId);
            header.put(Constant.HEADER_APP_AUTH, "Bearer" + " " + accessToken);

            HttpResponse httpResponse = httpsUtil.doDelete(urlSubscribe,header);
            bodySubscribe = httpsUtil.getHttpResponseBody(httpResponse);
            System.out.print(httpResponse.getStatusLine());
            System.out.println(bodySubscribe);
            System.out.println();
        }catch (Exception e){
            e.printStackTrace();
        }
        return ResultGenerator.genSuccessResult(bodySubscribe);
    }

    private String handler(String notifyType,String callbackUrl){
        String bodySubscribe = "";
        try {
            HttpsUtil httpsUtil = new HttpsUtil();
            httpsUtil.initSSLConfigForTwoWay();
            // Authentication，get token
            String accessToken = login(httpsUtil);
            //Please make sure that the following parameter values have been modified in the Constant file.
            String appId = Constant.APPID;
            String urlSubscribe = Constant.SUBSCRIBE_NOTIFYCATION;

            Map<String, Object> paramSubscribe = new HashMap<>();
            paramSubscribe.put("notifyType", notifyType);
            paramSubscribe.put("callbackUrl", callbackUrl);

            String jsonRequest = JsonUtil.jsonObj2Sting(paramSubscribe);

            Map<String, String> header = new HashMap<>();
            header.put(Constant.HEADER_APP_KEY, appId);
            header.put(Constant.HEADER_APP_AUTH, "Bearer" + " " + accessToken);

            HttpResponse httpResponse = httpsUtil.doPostJson(urlSubscribe, header, jsonRequest);

            bodySubscribe = httpsUtil.getHttpResponseBody(httpResponse);

            logger.info(httpResponse.getStatusLine()+"SubscribeNotification: " + notifyType);
            logger.info(bodySubscribe);
            System.out.println();
        }catch (Exception e){
            e.printStackTrace();
        }
        return bodySubscribe;
    }
    
    private String deletehandler(String notifyType,String callbackUrl){
        String bodySubscribe = "";
        try {
            HttpsUtil httpsUtil = new HttpsUtil();
            httpsUtil.initSSLConfigForTwoWay();
            // Authentication，get token
            String accessToken = login(httpsUtil);
            //Please make sure that the following parameter values have been modified in the Constant file.
            String appId = Constant.APPID;
            String urlSubscribe = Constant.SUBSCRIBE_NOTIFYCATION;


            Map<String, String> header = new HashMap<>();
            header.put(Constant.HEADER_APP_KEY, appId);
            header.put(Constant.HEADER_APP_AUTH, "Bearer" + " " + accessToken);

            HttpResponse httpResponse = httpsUtil.doDelete(urlSubscribe, header);

            bodySubscribe = httpsUtil.getHttpResponseBody(httpResponse);

            System.out.println("SubscribeNotification: " + notifyType + ", response content:");
            System.out.print(httpResponse.getStatusLine());
            System.out.println(bodySubscribe);
            System.out.println();
        }catch (Exception e){
            e.printStackTrace();
        }
        return bodySubscribe;
    }

    @SuppressWarnings("unchecked")
    public static String login(HttpsUtil httpsUtil) throws Exception {

        String appId = Constant.APPID;
        String secret = Constant.SECRET;
        String urlLogin = Constant.APP_AUTH;

        Map<String, String> paramLogin = new HashMap<>();
        paramLogin.put("appId", appId);
        paramLogin.put("secret", secret);

        StreamClosedHttpResponse responseLogin = httpsUtil.doPostFormUrlEncodedGetStatusLine(urlLogin, paramLogin);

        System.out.println("app auth success,return accessToken:");
        System.out.print(responseLogin.getStatusLine());
        System.out.println(responseLogin.getContent());
        System.out.println();

        Map<String, String> data = new HashMap<>();
        data = JsonUtil.jsonString2SimpleObj(responseLogin.getContent(), data.getClass());
        return data.get("accessToken");
    }
}
